//
// Created by tang on 22-9-7.
//

#include "window_callbacks.hpp"
#include <core/assert.hpp>
#include "window.hpp"
#include "input.hpp"

namespace core::app {
    void WindowCallbacks::AttachCallbacks(GLFWwindow *win)
    {
        CORE_ASSERT(win != nullptr);

        glfwSetKeyCallback(win, &WindowCallbacks::KeyCallback);
        glfwSetWindowSizeCallback(win, &WindowCallbacks::ResizeCallback);
        glfwSetMouseButtonCallback(win, &WindowCallbacks::MouseButtonCallback);
        glfwSetScrollCallback(win, &WindowCallbacks::ScrollCallback);
    }

    void WindowCallbacks::KeyCallback(GLFWwindow *window, int key, int scancode,
                                      int action, int mods)
    {
        auto *app = (Window *)glfwGetWindowUserPointer(window);
        auto &input = app->m_input;
        if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
            app->Quit();
        }

        LOG_D("Key board event: key: {}, scancode: {}, action: {}, mods: {}",
              key, scancode, action, mods);

        if (action == GLFW_RELEASE) {
            input.key_state[key] = false;
        } else {
            input.key_state[key] = true;
        }
    }

    void WindowCallbacks::ResizeCallback(GLFWwindow *window, int width,
                                         int height)
    {
        auto *app = (Window *)glfwGetWindowUserPointer(window);
        auto &input = app->m_input;

        input.resized = true;
        LOG_D("Window resized, new size is {}x{}", width, height);
    }

    void WindowCallbacks::MouseButtonCallback(GLFWwindow *window, int button,
                                              int action, int mods)
    {
        auto *app = (Window *)glfwGetWindowUserPointer(window);
        auto &input = app->m_input;

        LOG_D("Mouse Button button: {}, action: {}, mods: {}", button, action,
              mods);
        if (action == GLFW_RELEASE) {
            input.mouse_button_state[button] = false;
        } else {
            input.mouse_button_state[button] = true;
        }
    }

    void WindowCallbacks::ScrollCallback(GLFWwindow *window, double xdiff,
                                         double ydiff)
    {
        auto *app = (Window *)glfwGetWindowUserPointer(window);
        auto &input = app->m_input;

        LOG_D("Scrolling: dx: {}, dy: {}", xdiff, ydiff);
        input.wheel = {(f32)xdiff, (f32)ydiff};
    }

}  // namespace core::app
